import {defineComponent, PropType, reactive, getCurrentInstance, createApp} from 'vue';
import {ElButton, ElDialog, ElInput, ElTable, ElTableColumn} from "element-plus";
import deepcopy from 'deepcopy';
import {defer} from "@/packages/utils/defer";
import { VisualEditorProps } from '@/packages/visual-editor.props';

interface TablePropEditServiceOption {
    data?: any[],
    config: VisualEditorProps,
    onConfirm?: (val: any[]) => void,
    onCancel?: () => void,
}

const Component = defineComponent({
    props: {
        option: {type: Object as PropType<TablePropEditServiceOption>, required: true},
    },
    setup(props) {

        const ctx = getCurrentInstance()!

        const state = reactive({
            option: props.option,
            showFlag: false,
            data: [] as any[],
        })

        const methods = {
            service: (option: TablePropEditServiceOption) => {
                state.option = option
                state.showFlag = true
                state.data = deepcopy(option.data || [])
            },
            reset: () => {
                state.data = deepcopy(state.option.data || [])
            },
            add: () => {
                state.data.push({})
            },
            delete: (index: number) => {
                state.data.splice(index, 1)
            },
            save: () => {
                !!state.option.onConfirm && state.option.onConfirm(state.data)
                state.showFlag = false
            },
            cancel: () => {
                !!state.option.onCancel && state.option.onCancel()
                state.showFlag = false
            },
        }

        Object.assign(ctx.proxy, methods)

        return () => (
            // @ts-ignore
            <ElDialog v-model={state.showFlag} title="编辑选项信息">
                {{
                    default: () => <>
                        <div class="table-prop-editor-dialog-buttons">
                            <ElButton {...{onClick: methods.add} as any}>添加</ElButton>
                            <ElButton {...{onClick: methods.reset} as any}>重置</ElButton>
                        </div>
                        <div class="table-prop-editor-dialog-table">
                            <ElTable data={state.data}>
                                <ElTableColumn {...{type: 'index'} as any}/>
                                {(state.option.config.table?.options || []).map(col => (
                                    <ElTableColumn {...{label: col.label, prop: col.field} as any}>
                                        {{
                                            default: ({row}: { row: any }) => (
                                                <ElInput v-model={row[col.field]}/>
                                            ),
                                        }}
                                    </ElTableColumn>
                                ))}
                                <ElTableColumn {...{label: '操作栏'} as any}>
                                    {{
                                        default: ({row, $index}: { row: any, $index: number }) => (
                                            <ElButton {...{type: 'text', onClick: () => methods.delete($index)}}>
                                                删除
                                            </ElButton>
                                        ),
                                    }}
                                </ElTableColumn>
                            </ElTable>
                        </div>
                    </>,
                    footer: () => <>
                        <ElButton type="primary" {...{onClick: methods.save} as any}>保存</ElButton>
                        <ElButton {...{onClick: methods.cancel} as any}>取消</ElButton>
                    </>
                }}
            </ElDialog>
        )
    },
})

export const TablePropEditService = (() => {
    let ins: any;
    return (option: TablePropEditServiceOption) => {
        const dfd = defer<any[]>()
        option.onConfirm = dfd.resolve
        if (!ins) {
            const app = createApp(Component, {option})
            const el = document.createElement('div')
            document.body.appendChild(el)
            ins = app.mount(el)
        }
        ins.service(option)

        return dfd.promise
    }
})();